using System;
//using Linq;
using System.ComponentModel;
using System.Data;
//using Linq;
using System.Windows.Forms;
using Infragistics.Win.UltraWinEditors;
//using clsVariables;



public partial class Ctrl_ComboDoble : InterfazControles
{
    //bool bolPruebas = true;

    #region Propiedades Publicas

    public bool bolValoresCombosCorrectos
    {
        get
        {
            if (cmbIzquierda.Visible && cmbIzquierda.SelectedItem == null) { return false; }
            if (cmbDerecha.Visible && cmbDerecha.SelectedItem == null) { return false; }
            return true;
        }
    }

    #region                                                                Selectedindex
    //private object p_SelectedIndex;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Devuelve el SelectedIndex de combo establecido en propiedad\'ComboContieneValue\'"), Browsable(false)]
    public int SelectedIndex
    {
        get
        {
            //if (p_ComboContieneValue == e_ObjetoCombobox.Derecho) { return cmbDerecha.SelectedIndex; }
            //else { return cmbIzquierda.SelectedIndex; }

            return cmbDerecha.SelectedIndex; //EL dcho siempre está, cuando es 1 solo combo se oculta el izdo
        }
        set
        {
            //if (p_ComboContieneValue == e_ObjetoCombobox.Derecho) { cmbDerecha.SelectedIndex = SelectedIndex; }
            //else { cmbIzquierda.SelectedIndex = SelectedIndex; }

            cmbDerecha.SelectedIndex = SelectedIndex;
        }
    }
    #endregion
    //
    #region                                                                Value
    //private object p_Value;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Devuelve el value de combo establecido en propiedad\'ComboContieneValue\'"), Browsable(false)]
    public object Value
    {
        get
        {
            DataTable _DataTable = (DataTable)cmbDerecha.DataSource;

            if (_DataTable != null)
            {
                //// Console.WriteLine("1 get")
                //if (p_ComboContieneValue == e_ObjetoCombobox.Derecho)
                //{ return cmbDerecha.Value; }
                //else
                //{ return cmbIzquierda.Value; }              
                return ObtenerValorCampoAdicional(m_ValueDelControl, e_ObjetoCombobox.Derecho);
            }
            else { return null; }
        }
        set
        {
            if (value != null && value != System.DBNull.Value)
            {
                //// Console.WriteLine("1 set")
                //if (p_ComboContieneValue == e_ObjetoCombobox.Derecho)
                //{ cmbDerecha.Value = value; }
                //else
                //{ cmbIzquierda.Value = value; }


                //Obtener la row del cmb dcho q tiene ese valor

                DataTable _DataTable = (DataTable)cmbDerecha.DataSource;

                if (_DataTable != null)
                {
                    //if (value is string)
                    DataRow[] _Drs;
                    try
                    {
                        _Drs = _DataTable.Select(m_ValueDelControl + "=" + value);
                        if (_Drs.Length > 0) _Drs = _DataTable.Select(m_ValueDelControl + "='" + value + "'");
                    }
                    catch (Exception)
                    {
                        try { _Drs = _DataTable.Select(m_ValueDelControl + "='" + value + "'"); }
                        catch (Exception) { throw; }
                    }

                    if (_Drs.Length > 0) cmbDerecha.Value = _Drs[0][m_ValueComboDerecho];
                }
            }
        }
    }
    #endregion
    //
    #region                                                                Enabled
    private bool p_Enabled;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Si está habilitado o no el control")]
    public bool Enabled
    {
        get
        {
            return p_Enabled;
        }
        set
        {
            p_Enabled = value; cmbIzquierda.Enabled = value; cmbDerecha.Enabled = value;
        }
    }
    #endregion
    //
    //#region                                                                ComboContieneValue
    //private e_ObjetoCombobox p_ComboContieneValue = e_ObjetoCombobox.Derecho;
    //[Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("El combo que muestra el display tipo descripción (y por lo tanto contiene el value)")]
    //public e_ObjetoCombobox ComboContieneValue
    //{
    //    get
    //    {
    //        // Console.WriteLine("3 get")
    //        return p_ComboContieneValue;
    //    }
    //    set
    //    {
    //        // Console.WriteLine("3 set")
    //        p_ComboContieneValue = value;
    //    }
    //}
    //#endregion
    //
    #region  bol_Independiente
    private bool p_bol_Independiente = false;
    /// <summary>
    /// Indica si el control es independiente o obtiene/graba su valor en la bbdd
    /// </summary>
    /// <value></value>
    /// <returns></returns>
    /// <remarks></remarks>
    [Category(clsVariables.str_NombreAplicacion), Description("Indica si el control es independiente o obtiene/graba su valor en la bbdd")]
    public bool bol_Independiente
    {
        get
        {
            // Console.WriteLine("4 get")
            return p_bol_Independiente;
        }
        set
        {
            // Console.WriteLine("4 set")
            p_bol_Independiente = value;
        }
    }
    #endregion
    //
    #region                                                                TipoCampo
    private eTipoCampo p_TipoCampo = eTipoCampo.Editable;
    [Category(clsVariables.str_NombreAplicacion), Description("Indica si el control es clave, elazado o editable")]
    public eTipoCampo TipoCampo
    {
        get
        {
            // Console.WriteLine("5 get")
            return p_TipoCampo;
        }
        set
        {
            // Console.WriteLine("5 set")
            p_TipoCampo = value;
        }
    }
    #endregion
    //
    #region Datos
    #region                                                                TipoDatos
    private clsVariables.e_TipoOrigen p_TipoDatos;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Si los datos salen de cliente o de sistema")]
    public clsVariables.e_TipoOrigen TipoDatos
    {
        get
        {
            // Console.WriteLine("6 get")
            return p_TipoDatos;
        }
        set
        {
            // Console.WriteLine("6 set")
            p_TipoDatos = value;
        }
    }
    #endregion
    //'
    #region No usado
    public enum e_TipoConexion
    {
        SqlServer
    }
    //'
    private e_TipoConexion m_TipoConexion = e_TipoConexion.SqlServer;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Obligatorio. De q tipo de OrigenDeDatos extrae los datos los combos"), Browsable(false)]
    public e_TipoConexion TipoConexion
    {
        get
        {
            // Console.WriteLine("7 get")
            return m_TipoConexion;
        }
        set
        {
            // Console.WriteLine("7 set")
            m_TipoConexion = value;
            RellenarCadenaConexion();
        }
    }
    //
    private string m_NombreServidorDatos = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. En caso de no informar \'OrigenDeDatos\'. El nombre del servidor"), Browsable(false)]
    public string NombreServidorDatos
    {
        get
        {
            // Console.WriteLine("8 get")
            return m_NombreServidorDatos;
        }
        set
        {
            // Console.WriteLine("8 set")
            m_NombreServidorDatos = value.Trim();
            RellenarCadenaConexion();
        }
    }

    private string m_InitialCalatog = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. En caso de no informar \'OrigenDeDatos\'. El nombre de la tabla"), Browsable(false)]
    public string InitialCalatog
    {
        get
        {
            // Console.WriteLine("9 get")
            return m_InitialCalatog;
        }
        set
        {
            // Console.WriteLine("9 set")
            m_InitialCalatog = value.Trim();
            RellenarCadenaConexion();
        }
    }

    private string m_User = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. En caso de no informar \'OrigenDeDatos\'. El usuario de la base de datos"), Browsable(false)]
    public string User
    {
        get
        {
            // Console.WriteLine("10 get")
            return m_User;
        }
        set
        {
            // Console.WriteLine("10 set")
            m_User = value.Trim();
            RellenarCadenaConexion();
        }
    }

    private string m_Password = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. En caso de no informar \'OrigenDeDatos\'. El password de la base de datos"), Browsable(false)]
    public string Password
    {
        get
        {
            // Console.WriteLine("11 get")
            return m_Password;
        }
        set
        {
            // Console.WriteLine("11 set")
            m_Password = value.Trim();
            RellenarCadenaConexion();
        }
    }

    private bool m_SeguridadIntegrada = false;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("La propiedad \'Integrated Secutrity\'  de la conexión (para usar conexión por Windows o por SQL(u otro))" + ". True = Usa autentificación Windows"), Browsable(false)]
    public bool SeguridadIntegrada
    {
        get
        {
            // Console.WriteLine("12 get")
            return m_SeguridadIntegrada;
        }
        set
        {
            // Console.WriteLine("12 set")
            m_SeguridadIntegrada = value;
            if (value)
            {
                User = string.Empty;

                this.Password = string.Empty;
            }
            RellenarCadenaConexion();
        }
    }

    private string m_CadenaConexion = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. La cadena de conexión. Equivale a escribir \'Nombre\', \'Initial Catalog\', \'User\' y \'Pass\'."), Browsable(false)]
    public string CadenaConexion
    {
        get
        {
            // Console.WriteLine("13 get")
            return m_CadenaConexion;
        }
        set
        {
            // Console.WriteLine("13 set")
            m_CadenaConexion = value;
        }
    }
    #endregion
    //'
    private string m_TablaExtraenDatos = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. Indica la tabla de donde extrae los datos los combobox.")]
    public string TablaExtraenDatos
    {
        get
        {
            // Console.WriteLine("14 get")
            return m_TablaExtraenDatos;
        }
        set
        {
            // Console.WriteLine("14 set")
            m_TablaExtraenDatos = value.Trim();
        }
    }

    private string m_FiltroTabla = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'OrigenDatos\'. El Filtro que se aplica a los " + "registros recuperados de la tabla indicada.Ej: 1=1")]
    public string FiltroTabla
    {
        get
        {
            // Console.WriteLine("15 get")
            return m_FiltroTabla;
        }
        set
        {
            // Console.WriteLine("15 set")
            m_FiltroTabla = value.Trim();
        }
    }

    private bool m_CargarCombosAutomatico = true;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("Opcional. Al acabar de crear el control llama al procedimiento \'CargarCombos\' " + "para empezar la carga de datos. \'Verdadero\' cuando se hayan introducido los datos necesarios  del control en diseño.")]
    public bool CargarCombosAutomatico
    {
        get
        {
            // Console.WriteLine("16 get")
            return m_CargarCombosAutomatico;
        }
        set
        {
            // Console.WriteLine("16 set")
            m_CargarCombosAutomatico = value;
        }
    }

    private object m_OrigenDeDatos = null;
    [Category(clsVariables.str_NombreAplicacion + "-Datos Combos"), Description("No se cumplimenta si se informa \'CadenaConexion\'. El DataSource de los dos combos. Si se informa esto no se tiene que informar " + "ningún elemento más de \'Ageinfo-Datos\'. Solo accesible en tiempo de ejecución")]
    public object OrigenDeDatos
    {
        get
        {
            // Console.WriteLine("17 get")
            return m_OrigenDeDatos;
        }
        set
        {
            // Console.WriteLine("17 set")
            m_OrigenDeDatos = value;
            if (m_OrigenDeDatos != null)
            {
                ReCargaCombos("", null, null); //Tb llama al superavalidaciones
                //Limpieza todo lo demás si se cargo con éxito
                if (cmbDerecha.DataSource != null)
                {
                    NombreServidorDatos = string.Empty;

                    InitialCalatog = string.Empty;
                    User = string.Empty;

                    Password = string.Empty;
                    CadenaConexion = string.Empty;
                    FiltroTabla = string.Empty;

                    TablaExtraenDatos = string.Empty;
                }
            }
        }
    }
    #endregion
    //
    #region Propios ComboBox

    public enum e_ObjetoCombobox
    {
        Izquierdo,
        Derecho,
        Ninguno
    }
    public enum eTipoCombo
    {
        //UltraCombo
        //Combobox
        UltraComboEditor
    }
    public enum e_Orden
    {
        Ascendente,
        Descendente
    }
    public enum e_TipoCombo
    {
        Padre,
        Dependiente_Hijo,
        Normal
    }


    #region Combo Dcho
    private e_Orden m_OrdenDcho = e_Orden.Ascendente;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Dcho"), Description("Opcional. Como se ordena el display del combo. Ascendente o descendente.")]
    public e_Orden OrdenDcho
    {
        get
        {
            // Console.WriteLine("18 get")
            return m_OrdenDcho;
        }
        set
        {
            // Console.WriteLine("18 set")
            m_OrdenDcho = value;
        }
    }

    private string m_ValueDelControl = string.Empty;
    [Category(clsVariables.str_NombreAplicacion), Description("Obligatorio. Indica el Value del control. No se especifica ni dcho ni izdo pq. es del control en general.")]
    public string ValueDelControl
    {
        get
        {
            // Console.WriteLine("19 get")
            return m_ValueDelControl;
        }
        set
        {
            // Console.WriteLine("19 set")
            m_ValueDelControl = value.Trim();
        }
    }

    private string m_ValueComboDerecho = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Dcho"), Description("Obligatorio. Indica el Value del comboBox Derecho. El izquierdo se obtiene automático")]
    public string ValueComboDerecho
    {
        get
        {
            // Console.WriteLine("19 get")
            return m_ValueComboDerecho;
        }
        set
        {
            // Console.WriteLine("19 set")
            m_ValueComboDerecho = value.Trim();
        }
    }

    private string m_DisplayComboDerecho = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Dcho"), Description("Obligatorio. Indica el Display Text del comboBox Derecho. El izquierdo se obtiene automático")]
    public string DisplayComboDerecho
    {
        get
        {
            // Console.WriteLine("20 get")
            return m_DisplayComboDerecho;
        }
        set
        {
            // Console.WriteLine("20 set")
            m_DisplayComboDerecho = value.Trim();
        }
    }



    private string m_ValueComboIzquierdo = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Izdo"), Description("Opcional. Indica el Value del comboBox Izdo. en caso q sea distinto q el display del combo dcho")]
    public string ValueComboIzquierdo
    {
        get
        {
            // Console.WriteLine("20 get")
            return m_ValueComboIzquierdo;
        }
        set
        {
            // Console.WriteLine("20 set")
            m_ValueComboIzquierdo = value.Trim();
        }
    }

    private string m_DisplayComboIzquierdo = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Izdo"), Description("Opcional. Indica el Display Text del comboBox Izdo. en caso q sea distinto q el value del combo dcho")]
    public string DisplayComboIzquierdo
    {
        get
        {
            // Console.WriteLine("20 get")
            return m_DisplayComboIzquierdo;
        }
        set
        {
            // Console.WriteLine("20 set")
            m_DisplayComboIzquierdo = value.Trim();
        }
    }


    private int m_AnchoContenidoComboDcho = 0;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Dcho"), Description("Opcional. Corresponde al DropdownListWith del combo Dcho (el ancho del contenido).")]
    public int AnchoContenidoComboDcho
    {
        get
        {
            // Console.WriteLine("21 get")
            return m_AnchoContenidoComboDcho;
        }
        set
        {
            // Console.WriteLine("21 set")
            m_AnchoContenidoComboDcho = value;
            cmbDerecha.DropDownListWidth = m_AnchoContenidoComboDcho;
        }
    }
    #endregion

    #region Combo Izdo
    private e_Orden m_OrdenIzdo = e_Orden.Ascendente;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Izdo"), Description("Opcional. Como se ordena el display del combo. Ascendente o descendente.")]
    public e_Orden OrdenIzdo
    {
        get
        {
            // Console.WriteLine("22 get")
            return m_OrdenIzdo;
        }
        set
        {
            // Console.WriteLine("22 set")
            m_OrdenIzdo = value;
        }
    }

    private int m_AnchoComboIzquierda = 50;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Izdo"), Description("Opcional. El ancho del primer combo")]
    public int AnchoComboIzquierda
    {
        get
        {
            // Console.WriteLine("23 get")
            return m_AnchoComboIzquierda;
        }
        set
        {
            //El ancho máximo ha de ser de un 90% del ancho del control personalizado
            if (!SuperaAnchoMaximo(value))
            {
                // Console.WriteLine("23 set")
                m_AnchoComboIzquierda = value;
                CambiarAnchosCombos();
            }
        }
    }

    private int m_AnchoContenidoComboIzdo = 0;
    [Category(clsVariables.str_NombreAplicacion + "-Combo Izdo"), Description("Opcional. Corresponde al DropdownListWith del combo Izdo (el ancho del contenido).")]
    public int AnchoContenidoComboIzdo
    {
        get
        {
            // Console.WriteLine("24 get")
            return m_AnchoContenidoComboIzdo;
        }
        set
        {
            // Console.WriteLine("24 set")
            m_AnchoContenidoComboIzdo = value;
            cmbIzquierda.DropDownListWidth = m_AnchoContenidoComboIzdo;
        }
    }
    #endregion

    private bool m_UnSoloCombo = false;
    [Category(clsVariables.str_NombreAplicacion + "-Combos"), Description("Opcional. Solo deja el combo de la derecha")]
    public bool UnSoloCombo
    {
        get
        {
            // Console.WriteLine("25 get")
            return m_UnSoloCombo;
        }
        set
        {
            // Console.WriteLine("25 set")
            m_UnSoloCombo = value;
            if (m_UnSoloCombo)
            {
                AnchoComboIzquierda = 0;
            }
            else
            {
                AnchoComboIzquierda = 100;
            }
        }
    }

    private eTipoCombo m_TipoControl = eTipoCombo.UltraComboEditor;
    [Category(clsVariables.str_NombreAplicacion + "-Combos"), Description("Obligatorio. Indica el tipo de combobox que usaremos. Se propaga al combo izquierdo.")]
    public eTipoCombo TipoControl
    {
        get
        {
            // Console.WriteLine("26 get")
            return m_TipoControl;
        }
        set
        {
            // Console.WriteLine("26 set")
            m_TipoControl = value;
        }
    }

    private Infragistics.Win.EmbeddableElementDisplayStyle m_DisplayStyleCombos = Infragistics.Win.EmbeddableElementDisplayStyle.Default;
    [Category(clsVariables.str_NombreAplicacion + "-Combos"), Description("Opcional. La propiedad DisplayStyle de los combos.")]
    public Infragistics.Win.EmbeddableElementDisplayStyle DisplayStyleCombos
    {
        get
        {
            // Console.WriteLine("27 get")
            return m_DisplayStyleCombos;
        }
        set
        {
            // Console.WriteLine("27 set")
            m_DisplayStyleCombos = value;
            cmbDerecha.DisplayStyle = m_DisplayStyleCombos;
            cmbIzquierda.DisplayStyle = m_DisplayStyleCombos;
        }
    }

    private string[] p_arrCamposAdicionales;
    [Category(clsVariables.str_NombreAplicacion + "-Combos"), Description("Opcional. ÇCampos adicionales que ha de recuperar el combo aparte del value y el display (separados por comas).")]
    public string[] arrCamposAdicionales
    {
        get
        { return p_arrCamposAdicionales; }
        set
        { p_arrCamposAdicionales = value; }
    }

    #endregion
    //
    #region Dependencias
    private e_TipoCombo m_TipoComboDependiente = e_TipoCombo.Normal;
    [Category(clsVariables.str_NombreAplicacion + "-Dependencias"), Description("Se informa en el hijo. La carga de este control depende de otro control \'Ctrl_ComboDoble\'?. " + "No puede tener \'OrigenDeDatos\' con está opción activada (pq si se usa " + " \'OrigenDeDatos\' ya deberían venir los datos filtrados)")]
    public e_TipoCombo TipoComboDependiente
    {
        get
        {
            // Console.WriteLine("28 get")
            return m_TipoComboDependiente;
        }
        set
        {
            // Console.WriteLine("28 set")
            m_TipoComboDependiente = value;
            //Tb tiene validaciones
            switch (value)
            {
                case e_TipoCombo.Normal:
                    ComboConValueCampoDependiente = e_ObjetoCombobox.Ninguno;
                    NombreControlDependiente = string.Empty;
                    CampoEnlazaCombosDependientes = string.Empty;
                    break;
                case e_TipoCombo.Padre:
                    if (ComboConValueCampoDependiente == e_ObjetoCombobox.Ninguno)
                    {
                        ComboConValueCampoDependiente = e_ObjetoCombobox.Derecho;
                    }
                    break;
                //OrigenDeDatos = Nothing ' NO puede tener origen de datos
                case e_TipoCombo.Dependiente_Hijo:
                    ComboConValueCampoDependiente = e_ObjetoCombobox.Ninguno;
                    CampoEnlazaCombosDependientes = string.Empty;
                    NombreControlDependiente = string.Empty;
                    cmbIzquierda.Enabled = false;
                    cmbDerecha.Enabled = false;
                    CargarCombosAutomatico = false;
                    break;
            }
        }
    }

    private string m_NombreControlDependiente = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Dependencias"), Description("Se informa en el padre. Nombre del control (hijo) Ctrl_ComboDoble que depende su carga del value " + "de uno de los combos de este control.")]
    public string NombreControlDependiente
    {
        get
        {
            // Console.WriteLine("29 get")
            return m_NombreControlDependiente;
        }
        set
        {
            // Console.WriteLine("29 set")
            m_NombreControlDependiente = value.Trim();
        }
    }

    private e_ObjetoCombobox m_ComboConValueCampoDependiente = e_ObjetoCombobox.Derecho;
    [Category(clsVariables.str_NombreAplicacion + "-Dependencias"), Description("Se informa en el padre. Combo Izdo o Dcho?. El value del combo contiene el \'CampoEnlazaCombosDependientes\'.")]
    public e_ObjetoCombobox ComboConValueCampoDependiente
    {
        get
        {
            // Console.WriteLine("30 get")
            return m_ComboConValueCampoDependiente;
        }
        set
        {
            // Console.WriteLine("30 set")
            m_ComboConValueCampoDependiente = value;
        }
    }

    private string m_CampoEnlazaCombosDependientes = string.Empty;
    [Category(clsVariables.str_NombreAplicacion + "-Dependencias"), Description("Se informa en el padre. Campo por el cual el combo dependiente (hijo) ha de filtrar sus datos.")]
    public string CampoEnlazaCombosDependientes
    {
        get
        {
            // Console.WriteLine("31 get")
            return m_CampoEnlazaCombosDependientes;
        }
        set
        {
            // Console.WriteLine("31 set")
            m_CampoEnlazaCombosDependientes = value.Trim();
        }
    }
    #endregion
    //
    #endregion

    #region Combos
    private bool SuperaAnchoMaximo(int AnchoSeIntentaPoner)
    {
        bool Ret = false;
        if (AnchoSeIntentaPoner > this.Width - 50)
        {
            MessageBox.Show("El ancho supera el máximo permitido. Aumente el tamaño del control.", clsVariables.str_NombreAplicacion, MessageBoxButtons.OK, MessageBoxIcon.Information);
            Ret = true;
        }
        return Ret;
    }

    private void CambiarAnchosCombos()
    {
        this.cmbDerecha.Left = cmbDerecha.Left - (cmbIzquierda.Width - m_AnchoComboIzquierda);
        this.cmbIzquierda.Width = m_AnchoComboIzquierda;
        //Ancho combo derecha es la diferencia
        this.cmbDerecha.Width = this.Width - m_AnchoComboIzquierda - 15; //px diferencia
    }
    //
    public void ReCargaCombos() { ReCargaCombos("", null, null); }
    //
    /// <summary>
    /// Lanza el evento de carga del combo/de los combos
    /// </summary>
    /// <param name="sender"></param>
    ///// <param name="e"></param>
    /// <remarks></remarks>
    public void ReCargaCombos(string strFiltroAdicional, System.Object sender, System.EventArgs e)
    {
        //   //If SuperaValidaciones() Then CargaCombos(sender, e)
        //   CargaCombos(FiltroAdicional, sender, e);
        //}

        //public void CargaCombos(string strFiltroAdicional, System.Object sender, System.EventArgs e)
        //{
        bool bolDatosCargados = true;

        try
        {
            //Ya supero validaciones
            if (SuperaValidaciones())
            {
                //Sino se ha establecido hacerlo automa.
                //if (string.IsNullOrWhiteSpace(m_ValueComboIzquierdo)) m_ValueComboIzquierdo = cmbDerecha.DisplayMember;
                //if (string.IsNullOrWhiteSpace(m_DisplayComboIzquierdo)) m_DisplayComboIzquierdo = cmbDerecha.ValueMember;
                if (string.IsNullOrWhiteSpace(m_ValueComboIzquierdo)) m_ValueComboIzquierdo = m_DisplayComboDerecho;
                if (string.IsNullOrWhiteSpace(m_DisplayComboIzquierdo)) m_DisplayComboIzquierdo = m_ValueComboDerecho;

                //Carga Datos
                if (m_OrigenDeDatos == null)
                {
                    DataTable Dt = ObtenerDatos(strFiltroAdicional);
                    if (Dt.Rows.Count == 0) { Dt = ObtenerDatos(strFiltroAdicional); } //CHAPUZA! no se pq. misterioso motivo solo en el combo doble cuando borras todos los registros en el nav y agregas uno nuevo no obtiene ok
                    cmbDerecha.DataSource = OrdenDataSource(ref Dt, DisplayComboDerecho);
                }
                else
                {
                    cmbDerecha.DataSource = m_OrigenDeDatos;
                }
                if (cmbDerecha.DataSource == null)
                {
                    bolDatosCargados = false;
                }

                //Combo Izda/Dcha (un solo combo o dos)
                if (bolDatosCargados)
                {
                    cmbDerecha.ValueMember = m_ValueComboDerecho;
                    cmbDerecha.DisplayMember = m_DisplayComboDerecho;
                    //OrdenCombos(cmbIzquierda, OrdenDcho)
                    if (!m_UnSoloCombo)
                    {
                        cmbIzquierda.ValueMember = m_ValueComboIzquierdo;
                        cmbIzquierda.DisplayMember = m_DisplayComboIzquierdo;
                        DataTable Dt = (DataTable)cmbDerecha.DataSource;
                        cmbIzquierda.DataSource = OrdenDataSource(ref Dt, cmbIzquierda.DisplayMember);
                        //OrdenCombos(cmbIzquierda, OrdenIzdo)
                    }
                }
            }

        }
            catch (Exception ex)
        {
            MensajeErrorAmpliado(ex, MessageBoxIcon.Exclamation, "");
        }
    }

    private DataTable OrdenDataSource(ref DataTable dt, string CampoOrden)
    {
        DataView dv = dt.DefaultView;
        dv.Sort = CampoOrden;
        dt = dv.ToTable();
        return dt;
    }

    //Private Sub OrdenCombos(ByVal cbx As Object, _
    //                        ByVal OrdenEscogido As e_Orden)
    //   'Orden 'TODO: Orden para otros tipos control
    //   With cbx
    //      Select Case OrdenEscogido
    //         Case e_Orden.Ascendente
    //            Select Case TipoControl
    //               Case eTipoCombo.UltraComboEditor
    //                  .SortStyle = Infragistics.Win.ValueListSortStyle.Ascending
    //            End Select
    //         Case e_Orden.Descendente
    //            Select Case TipoControl
    //               Case eTipoCombo.UltraComboEditor
    //                  .SortStyle = Infragistics.Win.ValueListSortStyle.Descending
    //            End Select
    //      End Select
    //   End With
    //End Sub
    #endregion

    #region Eventos Combo
    #region ValueChange
    public delegate void ValueChangedHandler(object sender, System.EventArgs e); // Declare the delegate (if using non-generic pattern).
    public event ValueChangedHandler ValueChangeDcho; // Declare the event.
    #endregion
    //
    private Form DevolverFormPadre(Control parent)
    {
        Form Pform = parent as Form;
        if (Pform != null)
        {
            return Pform;
        }
        if (parent != null)
        {
            return DevolverFormPadre(parent.Parent);
        }
        return null;
    }

    //public void cmbDerecha_ValueChanged(System.Object sender, System.EventArgs e)
    //{      
    //}

    private void cmbDerecha_SelectionChanged(object sender, EventArgs e)
    {
        if (ValueChangeDcho != null) ValueChangeDcho(sender, e); //Lanzar evento
        //
        //Dim TextoCombo As String = cmbDerecha.SelectedItem.DisplayText.Trim
        if (cmbIzquierda.Focused == false)
        {
            //if (cmbDerecha.SelectedIndex != -1) //AndAlso TextoCombo <> String.Empty Then
            if (cmbDerecha.Value != null &&
                !string.IsNullOrWhiteSpace(cmbDerecha.Value.ToString())) //AndAlso TextoCombo <> String.Empty Then
            {
                cmbIzquierda.SelectionChanged -= cmbIzquierda_SelectionChanged;
                // cmbDerecha.SelectedItem.DisplayText.Trim(); //TextoCombo
                cmbIzquierda.Value = ObtenerValorCampoAdicional(m_ValueComboIzquierdo, e_ObjetoCombobox.Derecho);
                cmbIzquierda.SelectionChanged += cmbIzquierda_SelectionChanged;
            }
            else
            {
                cmbIzquierda.Value = null;
            }

            //Buscar combos dependientes
            CargarComboDependiente();
        }
    }

    //public void cmbIzquierda_ValueChanged(System.Object sender, System.EventArgs e)
    //{
    //}

    private void cmbIzquierda_SelectionChanged(object sender, EventArgs e)
    {
        //Dim TextoCombo As String = cmbIzquierda.SelectedItem.DisplayText.Trim
        if (cmbDerecha.Focused == false)
        {
            //if (cmbIzquierda.SelectedIndex != -1) //AndAlso TextoCombo <> String.Empty Then
            if (cmbIzquierda.Value != null &&
                cmbIzquierda.Value != System.DBNull.Value &&
                !string.IsNullOrWhiteSpace(cmbIzquierda.Value.ToString())) //AndAlso TextoCombo <> String.Empty Then
            {
                //.Value = cmbIzquierda.SelectedItem.DataValue
                cmbDerecha.SelectionChanged -= cmbDerecha_SelectionChanged;
                //cmbDerecha.Value =  cmbIzquierda.SelectedItem.DisplayText; //TextoCombo
                cmbDerecha.Value = ObtenerValorCampoAdicional(m_ValueComboDerecho, e_ObjetoCombobox.Izquierdo);

                if (ValueChangeDcho != null) ValueChangeDcho(sender, e); //Lanzar evento
                cmbDerecha.SelectionChanged += cmbDerecha_SelectionChanged;
            }
            else
            { cmbDerecha.Value = null; }
            CargarComboDependiente(); //Buscar combos dependientes
        }
    }

    /// <summary>
    /// Limpia el texto de cada combo y pone selectedindex = -1
    /// </summary>
    public void Clear()
    {
        cmbDerecha.SelectedIndex = -1; cmbDerecha.Text = "";
        cmbIzquierda.SelectedIndex = -1; cmbIzquierda.Text = "";
    }
    //
    /// <summary>
    /// Limpia el texto de cada combo y pone selectedindex = -1
    /// </summary>
    public void Limpiar()
    { Clear(); }
    //
    private void CargarComboDependiente()
    {
        //TODO: Incluir más de un combo dependiente (para poder cargar varios hijos)
        //Buscar combos dependientes
        if (TipoComboDependiente != e_TipoCombo.Normal && NombreControlDependiente != string.Empty)
        {
            Form FormPadre;
            Ctrl_ComboDoble Ctrl = null;
            string ValueComboPadre = string.Empty;

            //Obtener el form padre
            FormPadre = DevolverFormPadre(this.Parent);

            //Obtener el control hijo indicado
            try
            {
                Ctrl = (Ctrl_ComboDoble)FormPadre.Controls[NombreControlDependiente];
            }
            catch (Exception)
            {
                Ctrl = null;
            }

            //Obtener el value del combo padre
            if (Ctrl != null)
            {
                if (ComboConValueCampoDependiente == e_ObjetoCombobox.Derecho)
                {
                    switch (TipoControl)
                    {
                        case eTipoCombo.UltraComboEditor: //TODO: Más tipos combo
                            ValueComboPadre = (string)cmbDerecha.Value;
                            break;
                    }

                }
                else
                {
                    switch (TipoControl)
                    {
                        case eTipoCombo.UltraComboEditor:
                            ValueComboPadre = (string)cmbIzquierda.Value;
                            break;
                    }
                }

                //Cargar Combo hijo (si ValueComboPadre es string.Empty no cargará hijos)
                Ctrl.IniciaCargaComboDependiente(CampoEnlazaCombosDependientes, ValueComboPadre);
            }

        }
    }
    #endregion

    #region New/Load
    //Public Sub New()
    //   'Llamada necesaria para el Diseñador de Windows Forms.
    //   InitializeComponent()
    //End Sub

    public void Ctrl_ComboDoble_Load(object sender, System.EventArgs e)
    {
        //Si tiene activada la carga automática y no es combo dependiente cargamos combos
        if (!DesignMode && m_CargarCombosAutomatico && !bol_Independiente && m_TipoComboDependiente == e_TipoCombo.Normal)
        {
            ReCargaCombos("", null, null);
        }
        //
        //Esto lo hace el mtoBase no hace falta aquí
        //cmbDerecha.Enabled = eTipoCampo.Editable
        //cmbIzquierda.Enabled = eTipoCampo.Editable
        //Enabled = eTipoCampo.Editable      
    }
    #endregion

    #region Datos
    private void RellenarCadenaConexion()
    {
        //Según tipo conexión
        switch (m_TipoConexion)
        {
            case e_TipoConexion.SqlServer:
                CadenaConexion = "Data Source=" + m_NombreServidorDatos + ";Initial Catalog=" + m_InitialCalatog + ";integrated security=" + m_SeguridadIntegrada + ";persist security info=False;" + "Connection Timeout=0;";
                if (!m_SeguridadIntegrada)
                {
                    CadenaConexion += "user id=" + m_User + ";pwd=" + m_Password + ";";
                }
                m_OrigenDeDatos = null;
                break;
        }
    }

    #region  Validaciones
    private bool SuperaValidaciones()
    {
        bool Ret = true;
        string MensajeDeError = string.Empty;

        //Conexión o Datasource
        if (m_OrigenDeDatos == null && m_CadenaConexion == string.Empty)
        {
            MensajeDeError = "Falta indicar la cadena de conexión o cumplimentar la sección \'Ageinfo-Datos Combos\'.";
            Ret = false;
            //Si se informó cadena conexión
            //ElseIf m_CadenaConexion <> String.Empty Then
            //   If String.IsNullOrEmpty(m_InitialCalatog) Then
            //      MensajeDeError = "Falta indicar el InitialCalatog."
            //      Ret = False
            //   ElseIf String.IsNullOrEmpty(m_User) Then
            //      MensajeDeError = "Falta indicar el User."
            //      Ret = False
            //   ElseIf String.IsNullOrEmpty(m_Password) Then
            //      MensajeDeError = "Falta indicar el Password."
            //      Ret = False
            //   ElseIf String.IsNullOrEmpty(m_NombreServidorDatos) Then
            //      MensajeDeError = "Falta indicar el Nombre del Servidor."
            //      Ret = False
            //   End If
            //End If
        }

        //Conexión con autenficación  Windows
        if (m_SeguridadIntegrada && m_User != string.Empty && m_Password != string.Empty)
        {
            MensajeDeError = "No se puede escojer seguridad integrada y utilizar \'Password\' y \'User\'.";
            Ret = false;
        }

        //Dependencias
        if (m_TipoComboDependiente == e_TipoCombo.Padre)
        {
            //Campo Enlaza Combos Dependientes
            if (CampoEnlazaCombosDependientes == string.Empty)
            {
                MensajeDeError = "Con \'TipoCombo\' como padre, falta indicar la propiedad \'CampoEnlazaCombosDependientes\'";
                Ret = false;
            }
            //ComboConValueCampoDependiente
            if (ComboConValueCampoDependiente == e_ObjetoCombobox.Ninguno)
            {
                MensajeDeError = "Con \'TipoCombo\' como padre, falta indicar la propiedad \'ComboConValueCampoDependiente\'";
                Ret = false;
            }
            //NombreControlDependiente
            if (NombreControlDependiente == string.Empty)
            {
                MensajeDeError = "Con \'TipoCombo\' como padre, falta indicar la propiedad \'NombreControlDependiente\'";
                Ret = false;
            }
        }

        //Value y Display Combo
        if (string.IsNullOrEmpty(m_TablaExtraenDatos) && m_OrigenDeDatos == null)
        {
            MensajeDeError = "Se ha de informar la tabla de donde extrae los datos los combobox.";
            Ret = false;
        }
        else if (string.IsNullOrEmpty(ValueDelControl))
        {
            MensajeDeError = "Se ha de informar el campo del cual el control get/set el value.";
            Ret = false;
        }
        else if (string.IsNullOrEmpty(m_ValueComboDerecho) || string.IsNullOrEmpty(m_DisplayComboDerecho))
        {
            MensajeDeError = "Se ha de informar un Value y un Display para el \'Combo Derecho\' (el cbx izdo es automático).";
            Ret = false;
        }
        else if (m_FiltroTabla.ToLower().IndexOf("where") + 1 > 0)
        {
            m_FiltroTabla = m_FiltroTabla.Replace("where", string.Empty);
        }

        //Mje Error
        if (!Ret)
        {
            MensajeErrorAmpliado(null, MessageBoxIcon.Exclamation, MensajeDeError);
        }

        return Ret;
    }
    #endregion
    //
    /// <summary>
    /// Si tiene campos adicionales le pasas el título del campo y te devuelve el valor de la fila actual seleccionada
    /// Si hay algún error lanza msgbox y devuelve null
    /// </summary>
    /// <param name="strCampoAdicional"></param>
    /// <returns></returns>
    public object ObtenerValorCampoAdicional(string strCampoAdicional, e_ObjetoCombobox _e_ObjetoCombobox)
    {
        object Ret = null;
        UltraComboEditor _UltraComboEditor = _e_ObjetoCombobox == e_ObjetoCombobox.Derecho ? cmbDerecha : cmbIzquierda;

        if (_e_ObjetoCombobox == e_ObjetoCombobox.Derecho && _UltraComboEditor.SelectedItem == null) { Ret = 0; } //POr si se llama a ObtenerValorCampoAdicional antes q el combo tenga valores... para q devuelva 0 y por lo tanto en la sql ningún registro
        else if (_e_ObjetoCombobox == e_ObjetoCombobox.Izquierdo && _UltraComboEditor.SelectedItem == null) { Ret = 0; }
        else
        {
            //Si tiene datos el combo
            if (_UltraComboEditor.DataSource == null) { throw new Exception("El combo no tiene datasource asignado"); }
            try
            {
                //Si se produce error es pq la columna no existe
                {//Da igual si recupera de un combo o de otro. Cogo el dcho mismo
                    Ret = ((System.Data.DataRowView)_UltraComboEditor.SelectedItem.ListObject).Row[strCampoAdicional];
                }
            }
            catch (Exception ex)
            { MessageBox.Show(String.Format("No existe la columna '{0}'. Error: {1}", strCampoAdicional, ex.Message)); }
        }
        return Ret;
    }
    //
    public virtual DataTable ObtenerDatos(string FiltroAdicional)
    {
        //Dim cn As SqlClient.SqlConnection = Nothing
        //Dim daTit As SqlClient.SqlDataAdapter = Nothing
        string Ssql = string.Empty;
        //string arrCamposExtraSql = arrCamposAdicionales.ToString;
        //Dim dsDatos As DataSet = Nothing
        //Dim Ret As DataTable = Nothing

        //Try
        //   Select Case m_TipoConexion
        //      Case e_TipoConexion.SqlServer
        Ssql = String.Format("Select {0}{1},{2}{3}{4} From {5} Where 1 = 1",
           m_ValueComboDerecho,
           m_DisplayComboDerecho == m_ValueComboIzquierdo ? "" : "," + m_DisplayComboDerecho,
           m_ValueComboIzquierdo,
            //string.IsNullOrWhiteSpace(m_DisplayComboIzquierdo) ? "" : "," + m_DisplayComboIzquierdo,
            m_DisplayComboIzquierdo == m_ValueComboDerecho ? "" : "," + m_DisplayComboIzquierdo,
           (arrCamposAdicionales == null || arrCamposAdicionales.Length == 0 ?
           "" : "," + Utiles.Strings.ConvertStringArrayToString(arrCamposAdicionales, ",")),
            m_TablaExtraenDatos
           ); //& " Order By " & m_DisplayComboDerecho

        //'Añadir Filtro y filtro adicional
        if (m_FiltroTabla != string.Empty)
        {
            Ssql += " and " + m_FiltroTabla;
        }
        if (FiltroAdicional != string.Empty)
        {
            Ssql += " and " + FiltroAdicional;
        }

        //         'Obtener datos
        //         cn = New SqlClient.SqlConnection(m_CadenaConexion)
        //         daTit = New SqlClient.SqlDataAdapter(Ssql, cn)
        //         dsDatos = New DataSet
        //         daTit.Fill(dsDatos, "Datos")
        //         Ret = dsDatos.Tables(0)

        //         If Ret.Rows.Count > 0 Then
        //            Return Ret
        //         Else
        //            Return Nothing
        //         End If
        //      Case Else
        //         Return Nothing
        //   End Select

        //Catch ex As Exception
        //   MensajeErrorAmpliado(ex, , "Error en la conexión")
        //   Return Nothing
        //Finally
        //   'Limpieza
        //   If Not cn Is Nothing Then
        //      With cn
        //         .Close() : .Dispose()
        //      End With
        //   End If
        //   If Not daTit Is Nothing Then daTit.Dispose()
        //End Try
        //
        return clsBBDD.DtObtener(Ssql, TipoDatos, false); //General por factory
    }
    #endregion

    #region Combo Dependiente
    /// <summary>
    /// Este Sub es llamado desde un control padre. Fuerza la carga con el filtro escogido
    /// </summary>
    /// <param name="NombreCampoFiltro">Nombre del campo por el cual se hará el filtros</param>
    /// <param name="ValorCampoFiltro">Value del combo padre por el cual se filtrará el resultado del datasource del hijo</param>
    /// <remarks></remarks>
    public void IniciaCargaComboDependiente(string NombreCampoFiltro, string ValorCampoFiltro)
    {
        if (ValorCampoFiltro == string.Empty)
        {
            cmbIzquierda.Enabled = false;
            cmbDerecha.Enabled = false;
        }
        else
        {
            ReCargaCombos(NombreCampoFiltro + " = " + ValorCampoFiltro, null, null);
            cmbIzquierda.Enabled = true;
            cmbDerecha.Enabled = true;
        }
        cmbIzquierda.SelectedIndex = -1;
        cmbDerecha.SelectedIndex = -1;
    }
    #endregion

    private void Button1_Click(System.Object sender, System.EventArgs e)
    {
        //-------------PRUEBAS
        //'Valores directos
        //Me.CadenaConexion = "Data Source=AGI10\SQLEXPRESS;Initial Catalog=GPROY;Integrated Security=True;Connection TimeOut=0"
        //Me.TablaExtraenDatos = "Auditorias"
        //Me.ValueComboDerecho = "AuditoriaID"
        //Me.DisplayComboDerecho = "Descripcion"
        //Me.FiltroTabla = "Descripcion like '%Estados%'"
        //ReCargaCombos()

        //---------------

        //Valores(independientes(express))
        this.NombreServidorDatos = "AGI10\\SQLEXPRESS";
        this.InitialCalatog = "GPROY";
        this.SeguridadIntegrada = true;

        //Valores independientes (sqlServer)
        //Me.NombreServidorDatos = "GAIA"
        //Me.InitialCalatog = "GPROY"
        //Me.User = "sa"
        //Me.Password = "Admindnet2009"

        //Valores independientes Comun
        m_TablaExtraenDatos = "Auditorias";
        this.ValueComboDerecho = "AuditoriaID";
        this.DisplayComboDerecho = "Descripcion";
        this.FiltroTabla = "Descripcion like \'%Estados%\'";
        ReCargaCombos("", null, null);

        //-------------
        //'Paso datasource directo
        //Me.ValueComboDerecho = "AuditoriaID"
        //Me.DisplayComboDerecho = "Descripcion"
        //Dim cn As SqlClient.SqlConnection
        //Dim daTit As SqlClient.SqlDataAdapter
        //Dim dsTit As DataSet
        //cn = New SqlClient.SqlConnection("Data Source=AGI10\SQLEXPRESS;Initial Catalog=GPROY;Integrated Security=True;Connection TimeOut=0")
        //daTit = New SqlClient.SqlDataAdapter("select * from Auditorias", cn)
        //dsTit = New DataSet
        //daTit.Fill(dsTit, "DSSql")
        //Me.OrigenDeDatos = dsTit.Tables(0)

        //ReCargaCombos()
        //-------------PRUEBAS
    }

    /// <summary>
    /// Muestra un mje personalizado de error
    /// </summary>
    /// <param name="ExcepcionActual">Sino incluimos excepción mostrará el mensajeError solo</param>
    /// <param name="TipoMensaje"></param>
    /// <param name="MensajeError">Si añadimos MensajeError, mostrará este mensaje acompañado del err.message</param>
    /// <remarks></remarks>
    private void MensajeErrorAmpliado(Exception ExcepcionActual, MessageBoxIcon TipoMensaje, string MensajeError)
    {
        MensajeError = MensajeError.Trim();
        if (ExcepcionActual == null && MensajeError == string.Empty)
        {
            MensajeErrorAmpliado(null, MessageBoxIcon.Exclamation, "Se ha de indicar un mensaje o una exception");
        }
        else
        {
            if (ExcepcionActual != null)
            {
                if (MensajeError != string.Empty)
                {
                    MensajeError = MensajeError + ": ";
                }
                MensajeError += ExcepcionActual.Message;

                Console.WriteLine("Error: " + ExcepcionActual.StackTrace);
            }
            MessageBox.Show(Name + ": " + MensajeError, clsVariables.str_NombreAplicacion, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }

    public Ctrl_ComboDoble()
    {
        // Llamada necesaria para el Diseñador de Windows Forms.
        InitializeComponent();
        // Agregue cualquier inicialización después de la llamada a InitializeComponent().
    }




}




